# - 什么是迭代器?什么是生成器?两者有什么区别?
#   迭代器可以用来表示一个数据流, 提供了数据的惰性返回功能(只有我们主动去使用next方法调用, 才会返回值).
#   迭代器可以一次只返回一个元素, 占用内存非常小, 在读取大文件和大的数据集合的时候特别有用
#   生成器是一种特殊的迭代器, 在迭代器惰性返回数据的基础上, 提供了额外的功能, 实现了程序的暂停.
# 生成器和迭代器的区别?
# 同样提供了惰性返回的功能, 迭代器侧重于提供**数据**的惰性返回功能, 生成器侧重于**指令**的惰性返回功能

# - 协程的实现原理.:协程的实现原理就是生成器的实现原理, 在生成器的基础上又提供了传递值的功能.
# 对生成器进行`send`操作一定要调用`next`方法预激, 使其停留在第一个yield位置
# 通过`send`方法向生成器传递值
# def simple_coro(a):
#     print("初始值 a=", a)
#     b = yield a
#     print("传递值 b=", b)
#     c = yield a + b
#     print("传递值 c=", c)
#
# coro = simple_coro(1)
# print(next(coro))
# print(coro.send(2))


# - `asyncio`实现原理  用于IO异步请求, 网络请求,相当于多线程
# 自动维护了一个事件队列, 然后循环访问事件来完成异步的消息维护.
# 通过在函数前面加上 Asyncio 实现,导入import asyncio 包名
# 实现的过程中不允许阻塞, 当前异步实际上有没有提高效率, 也关乎到你调用的第三方是不是异步的.
# await asyncio.sleep(1) 这个函数可以让渡CPU资源,替换time.sleep(1)
# # 获取消息队列
# loop = asyncio.get_event_loop()
# # 包装任务
# task_array = []
# for i in range(100):
#     task_array.append(sim_request(i))
# # 循环访问事件来完成异步的消息维护
# loop.run_until_complete(asyncio.wait(task_array))
# # 关闭事件循环
# loop.close()

# 闭包实现求平均数的范例
# def make_averager():
#     series = []
#     def averager(value):
#         series.append(value)
#         total = sum(series)
#         return total / len(series)
#     return averager
#
# # my_avg就是延申了作用域的函数
# # series就是被延申作用域的变量
# my_avg = make_averager()
# print(my_avg(1))
# print(my_avg(2))
# - 用协程实现一个计算平均数的函数
import asyncio
import requests


def my_avg():
    total = 0
    length = 0
    while True:
        try:
            value = yield total/length
        except ZeroDivisionError:
            value = yield 0
        total += value
        length += 1


# - 编写一个`asyncio`异步程序

async def my_asyncio():
    await asyncio.sleep(1)
    # url = "https://www.zhihu.com/"  # 访问知乎
    # # body = ""
    # headers = {
    #     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"
    # }
    # response = requests.get(url=url, headers=headers)
    status_code = 200
    return status_code


def get_data(index):  # index输入访问次数
    loop = asyncio.get_event_loop()
    task_array = []
    for i in range(index):
        task_array.append(my_asyncio())
    result = loop.run_until_complete(asyncio.gather(*task_array))
    print(result)
    loop.close()


# - 扩展: 了解`aiohttp`异步请求网址
if __name__ == "__main__":
    my_result = my_avg()
    print(next(my_result))
    print(my_result.send(6))
    print(my_result.send(8))
    get_data(2)
